package com.qianyu.versioncontrolcore.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianyu.versioncontrolcore.entity.base.BaseIdDTO;
import com.qianyu.versioncontrolcore.entity.bean.VersionAreaConfig;
import com.qianyu.versioncontrolcore.entity.bean.VersionConf;
import com.qianyu.versioncontrolcore.entity.dto.VersionAreaConfigDto;
import com.qianyu.versioncontrolcore.entity.vo.AreaVo;
import com.qianyu.versioncontrolcore.exception.CustomerException;
import com.qianyu.versioncontrolcore.mapper.VersionAreaConfigMapper;
import com.qianyu.versioncontrolcore.mapper.VersionConfMapper;
import com.qianyu.versioncontrolcore.service.AreaService;
import com.qianyu.versioncontrolcore.service.VersionAreaConfigService;
import com.qianyu.versioncontrolcore.util.CacheKeyUtil;
import com.qianyu.versioncontrolcore.util.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.qianyu.versioncontrolcore.enumerate.ResultEnum.CITY_CONFIG_EXIST;

@Service
@RequiredArgsConstructor
public class VersionAreaConfigServiceImpl extends ServiceImpl<VersionAreaConfigMapper, VersionAreaConfig> implements VersionAreaConfigService {

    private final RedisUtil redisUtil;

    private final AreaService areaService;

//    private final VersionConfService versionConfService;
    private final VersionConfMapper versionConfMapper;

    @Override
    public void addAreaConfig(VersionAreaConfigDto.VersionAreaConfigAddDto dto) {
        validate(null, dto.getVersion(), dto.getAdcode());
        VersionAreaConfig config = BeanUtil.copyProperties(dto, VersionAreaConfig.class);
        save(config);
        redisUtil.set(CacheKeyUtil.versionAreaConfigSpace(dto.getVersion(), dto.getAdcode()), dto.getNumber(), dto.getSpace());
    }

    @Override
    public void editAreaConfig(VersionAreaConfigDto.VersionAreaConfigEditDto dto) {
        validate(dto.getId(), dto.getVersion(), dto.getAdcode());
        VersionAreaConfig config = BeanUtil.copyProperties(dto, VersionAreaConfig.class);
        updateById(config);
        redisUtil.set(CacheKeyUtil.versionAreaConfigSpace(dto.getVersion(), dto.getAdcode()), dto.getNumber(), dto.getSpace());
    }

    @Override
    public Page<VersionAreaConfig> pageList(VersionAreaConfigDto.VersionAreaConfigPageDto dto) {
        List<AreaVo.AreaListVo> list = areaService.listArea();
        Map<String, String> map = list.stream().collect(Collectors.toMap(AreaVo.AreaListVo::getAdcode, AreaVo.AreaListVo::getName));
        LambdaQueryWrapper<VersionAreaConfig> wrapper = Wrappers.lambdaQuery();
        if (!ObjectUtils.isEmpty(dto.getVersion())) {
            wrapper.like(VersionAreaConfig::getVersion, dto.getVersion());
        }
        if (!ObjectUtils.isEmpty(dto.getAdcode())) {
            wrapper.like(VersionAreaConfig::getAdcode, dto.getAdcode());
        }
        wrapper.eq(VersionAreaConfig::getStatus, 1);
        wrapper.orderByDesc(VersionAreaConfig::getCreateTime);
        Page<VersionAreaConfig> page = (Page<VersionAreaConfig>) page(new Page<>(dto.getPageNum(), dto.getPageSize()), wrapper);
        page.getRecords().forEach(v -> {
            v.setAreaName(map.get(v.getAdcode()));
        });
        return page;
    }

    @Override
    public VersionAreaConfig getConfig(String version, String adcode) {
        LambdaQueryWrapper<VersionAreaConfig> wrapper = Wrappers.lambdaQuery();
        wrapper.select(VersionAreaConfig::getAdcode, VersionAreaConfig::getNumber, VersionAreaConfig::getSpace)
                .eq(VersionAreaConfig::getVersion, version).eq(VersionAreaConfig::getAdcode, adcode)
                .eq(VersionAreaConfig::getStatus, 1);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public List<VersionAreaConfig> getList(String version) {
        LambdaQueryWrapper<VersionAreaConfig> wrapper = Wrappers.lambdaQuery();
        wrapper.select(VersionAreaConfig::getAdcode, VersionAreaConfig::getNumber, VersionAreaConfig::getSpace,
                VersionAreaConfig::getRemark).eq(VersionAreaConfig::getVersion, version).eq(VersionAreaConfig::getStatus, 1);
        return list(wrapper);
    }

    @Override
    public void deleteConfig(BaseIdDTO dto) {
        VersionAreaConfig config = baseMapper.selectById(dto.getId());
        if (redisUtil.hasKey(CacheKeyUtil.versionAreaConfigSpace(config.getVersion(), config.getAdcode()))) {
            redisUtil.del(CacheKeyUtil.versionAreaConfigSpace(config.getVersion(), config.getAdcode()));
        }
        update(Wrappers.<VersionAreaConfig>lambdaUpdate().set(VersionAreaConfig::getStatus, 0).eq(VersionAreaConfig::getId, dto.getId()));
    }

    @Override
    public List<VersionAreaConfig> getAllList() {
        LambdaQueryWrapper<VersionAreaConfig> wrapper = Wrappers.lambdaQuery();
        wrapper.select(VersionAreaConfig::getVersion, VersionAreaConfig::getAdcode, VersionAreaConfig::getNumber, VersionAreaConfig::getSpace,
                VersionAreaConfig::getRemark).eq(VersionAreaConfig::getStatus, 1);
        return list(wrapper);
    }

    @Override
    public void batchAdd() {
        List<VersionAreaConfig> list = new ArrayList<>();
//        List<VersionConfVo.VersionListVo> versionList = versionConfService.getVersionList();
        List<VersionConf> versionConfs = versionConfMapper.selectList(Wrappers.<VersionConf>lambdaQuery().select(VersionConf::getVersion).eq(VersionConf::getStatus, 1));
        List<AreaVo.AreaListVo> listVos = areaService.listArea();
        for (VersionConf v : versionConfs) {
            for (AreaVo.AreaListVo a : listVos) {
                VersionAreaConfig config = new VersionAreaConfig();
                config.setVersion(v.getVersion());
                config.setAdcode(a.getAdcode());
                list.add(config);
            }
        }
        saveBatch(list);
    }


    private void validate(Long id, String version, String adcode) {
        VersionAreaConfig one = baseMapper.selectOne(Wrappers.<VersionAreaConfig>lambdaQuery()
                .eq(VersionAreaConfig::getVersion, version)
                .eq(VersionAreaConfig::getAdcode, adcode)
                .ne(!ObjectUtils.isEmpty(id), VersionAreaConfig::getId, id));
        if (!ObjectUtils.isEmpty(one)) {
            throw new CustomerException(CITY_CONFIG_EXIST);
        }
    }
}
